/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Initial Developer of the Original Code is
*   Nick Kreeger
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Nick Kreeger <nick.kreeger@park.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#import "CompositionWindowController.h"
#import "CHMsgComposeWindow.h"
#import "CompositionWindow.h"
#import "Contact.h"
#import "NSString+Utils.h"
#import "CHMsgComposeWindow.h"
#import "AddressBookDlgController.h"
#import "AttachmentView.h"

// Toolbar Identifiers
static NSString* const kCompositionWindowToolbarIdentifier = @"CompositionWindowToolbarIdentifier";
static NSString* const kSendToolbarIdentifier = @"SendToolbarIdentifier";
static NSString* const kAttachToolbarIdentifier = @"AttachToolbarIdentifier";
static NSString* const kAddressBookToolbarIdentifier = @"AddressBookToolbarIdentifier";
static NSString* const kSaveToolbarIdentifier = @"SaveToolbarIdentifer";

NSString* const kCompositionWindowWillCloseNotification = @"CompositionWindowWillClose";

@interface CompositionWindowController(Private)

-(void)syncWindowWithDelegate;
-(void)setupToolbar;

-(void)prevalidateReceipents;

-(NSSet*)toContacts;
-(NSSet*)ccContacts;

-(void)openAttachmentPanelDidEnd:(NSOpenPanel*)sheet 
                      returnCode:(int)returnCode 
                     contextInfo:(void*)contextInfo;

@end

@implementation CompositionWindowController

//XXX Make this a handy static method.
-(id)init
{
  if ((self = [self initWithWindowNibName:@"CompositionWindow"]))
  {
    mCHBrowserView = [[CHBrowserView alloc] initWithFrame:NSZeroRect andWindow:[self window]];
    mMsgComposeWindow = new CHMsgComposeWindow();
    NS_IF_ADDREF(mMsgComposeWindow);
    
    mCompFieldsReady = NO;
    mCompBodyReady = NO;
    mIsComposeProcessDone = NO;
  }
  
  return self;
}

-(void)dealloc
{
  [mCHBrowserView destroyWebBrowser];
  [mCHBrowserView release];
    
  NS_IF_RELEASE(mMsgComposeWindow);
  mMsgComposeWindow = nsnull;
  
  [super dealloc];
}

-(void)windowDidLoad
{
  [super windowDidLoad];
  [self setupToolbar];
  [self syncWindowWithDelegate];
  
  [[self window] setDelegate:self];
}

-(void)windowWillClose:(NSNotification*)aNotification
{
  mMsgComposeWindow->WindowWillClose();
  [[NSNotificationCenter defaultCenter] postNotificationName:kCompositionWindowWillCloseNotification object:self];
  [[NSUserDefaults standardUserDefaults] synchronize];
}

- (BOOL)windowShouldClose:(id)sender 
{
  if ([[self window] isDocumentEdited])
  {
    //XXX add save dialog here...
    return NO;
  }
    
  return YES;
}

-(void)windowDidBecomeKey:(NSNotification*)aNotification
{
}

-(void)initializeComposer:(nsIMsgComposeParams*)aMsgComposeParams
{
  mMsgComposeWindow->Initialize(aMsgComposeParams, self, mCHBrowserView);
}

-(void)syncWindowWithDelegate
{
}

-(CHBrowserView*)browserView
{
  return mCHBrowserView;
}

-(void)addToContacts:(NSString*)aContactString
{
  if ([[mToField stringValue] isEqualToString:@""])
    [mToField setStringValue:[[mToField stringValue] stringByAppendingString:aContactString]];
  else
    [mToField setStringValue:[[mToField stringValue] stringByAppendingFormat:@", %@", aContactString]];
}

-(IBAction)send:(id)sender
{
  //XXX validate the email addresses in the composer fields!
  mMsgComposeWindow->SetToLiteral([mToField stringValue]);
  mMsgComposeWindow->SetCcLiteral([mCcField stringValue]);
  mMsgComposeWindow->SetSubject([mSubjectField stringValue]);
  mMsgComposeWindow->SetBodyLiteral([mComposerContentView bodyText]);
  mMsgComposeWindow->SetForcePlainText(YES);

  mMsgComposeWindow->SendMessage();
}

-(IBAction)cancelSend:(id)sender
{
  mMsgComposeWindow->AbortSend();
}

-(IBAction)attach:(id)sender
{
  NSOpenPanel* openPanel = [NSOpenPanel openPanel];
  [openPanel setCanChooseDirectories:NO];
  [openPanel beginSheetForDirectory:nil
                               file:nil
                     modalForWindow:[self window]
                      modalDelegate:self 
                     didEndSelector:@selector(openAttachmentPanelDidEnd:returnCode:contextInfo:)
                        contextInfo:nil];
}

-(IBAction)openAddressBook:(id)sender
{
  [[AddressBookDlgController sharedInstance] showWindow:self];
}

-(IBAction)saveAsDraft:(id)sender
{
}

-(BOOL)isComposeProcessDone
{
  return  mIsComposeProcessDone;
}

-(void)openAttachmentPanelDidEnd:(NSOpenPanel*)sheet 
                      returnCode:(int)returnCode 
                     contextInfo:(void*)contextInfo
{
  if (returnCode == NSOKButton)
  {
    NSURL* curUrl = nil;
    NSEnumerator* urlsEnum = [[sheet URLs] objectEnumerator];
    while ((curUrl = [urlsEnum nextObject]))
      mMsgComposeWindow->AddAttachment(curUrl);
    
    [mComposerContentView updateAttachmentList:mMsgComposeWindow->GetAttachmentArray()];
    [mComposerContentView showAttachments];
  }
}

-(void)prevalidateReceipents
{
  //XXX write me!
}

/**
 * For now all contacts are CSV:
 * foo@bar.com, bar@foo.com, etc...
 */
-(NSSet*)toContacts
{
  return [NSSet setWithArray:[[mToField stringValue] componentsSeparatedByString:@", "]];
}

-(NSSet*)ccContacts
{
  return [NSSet setWithArray:[[mCcField stringValue] componentsSeparatedByString:@", "]];
}

#pragma mark -

//
// ComposerStateListenerDelegate implementation
//
-(void)onComposeFieldsReady
{
  mCompFieldsReady = YES;
  
  [mToField setStringValue:mMsgComposeWindow->GetToLiteral()];
  [mCcField setStringValue:mMsgComposeWindow->GetCcLiteral()];
  [mSubjectField setStringValue:mMsgComposeWindow->GetSubject()];
  
  if (mCompBodyReady)
    [self showComposeWindow];
}

-(void)onComposeProcessDone
{
  mMsgComposeWindow->WindowWillClose();
  mIsComposeProcessDone = YES;
  
  [[self window] close];
}

-(void)onSaveInFolderDone:(NSString*)aFolderName
{
}

-(void)onComposeBodyReady:(NSString*)inBodyText
{
  mCompBodyReady = YES;
  [mComposerContentView setBodyText:inBodyText];
  
  if (mCompFieldsReady)
    [self showComposeWindow];
}

-(void)showComposeWindow
{
  mCompFieldsReady = YES;
  mCompBodyReady = YES;
  
  //XXX localize this.
  NSString* title = ([[mSubjectField stringValue] isEqualToString:@""] ? title = @"New Message" : [mSubjectField stringValue]);
  [[self window] setTitle:title];
  [self showWindow:self];
}

-(void)onStartSending
{
  [mSendProgWindow showProgressDialog];
}

-(void)showProgressDialog
{
  [mSendProgWindow showProgressDialog];
}

-(void)closeProgressDialog
{
  [mSendProgWindow stopPorgressDialog];
}

-(void)onProgress:(int)aProgress maxProgress:(int)aMaxProgress
{
  [mSendProgWindow updateProgress:aProgress maxProgress:aMaxProgress];
}

-(void)onStatus:(NSString*)aMessage
{
  [mSendProgWindow setStatusString:aMessage];
}

-(void)onSendNotPerformed
{
  [mSendProgWindow stopPorgressDialog];
}

#pragma mark -

-(void)setupToolbar
{
  NSToolbar* toolbar = [[[NSToolbar alloc] initWithIdentifier:kCompositionWindowToolbarIdentifier] autorelease];
  [toolbar setDelegate:self];
  [toolbar setAllowsUserCustomization:YES];
  [toolbar setAutosavesConfiguration:YES];
  [[self window] setToolbar:toolbar];
}

-(NSArray*)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
{
  return [NSArray arrayWithObjects:
    kSendToolbarIdentifier,
    kAttachToolbarIdentifier,
    kAddressBookToolbarIdentifier,
    kSaveToolbarIdentifier,
    NSToolbarPrintItemIdentifier,
    NSToolbarFlexibleSpaceItemIdentifier,
    NSToolbarSpaceItemIdentifier,
    NSToolbarSeparatorItemIdentifier,
    nil];
}

-(NSArray*)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
{
  return [NSArray arrayWithObjects:
    kSendToolbarIdentifier,
    NSToolbarSpaceItemIdentifier,
    kAttachToolbarIdentifier,
    kAddressBookToolbarIdentifier,
    kSaveToolbarIdentifier,
    NSToolbarPrintItemIdentifier,
    NSToolbarFlexibleSpaceItemIdentifier,
    NSToolbarSpaceItemIdentifier,
    nil];
}

-(NSToolbarItem*) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
  NSToolbarItem *theItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];
  
  if ([itemIdentifier isEqualToString:kSendToolbarIdentifier]) 
  {
    [theItem setLabel:NSLocalizedString(@"Send", nil)];
    [theItem setToolTip:NSLocalizedString(@"SendTooltip", nil)];
    [theItem setPaletteLabel:NSLocalizedString(@"SendButton", nil)];
    [theItem setAction:@selector(send:)];
    [theItem setImage:[NSImage imageNamed:@"sendmail.tif"]];
  }
  else if ([itemIdentifier isEqualToString:kAttachToolbarIdentifier])
  {
    [theItem setLabel:NSLocalizedString(@"Attach", nil)];
    [theItem setToolTip:NSLocalizedString(@"AttachToolTip", nil)];
    [theItem setPaletteLabel:NSLocalizedString(@"AttachButton", nil)];
    [theItem setAction:@selector(attach:)];
    [theItem setImage:[NSImage imageNamed:@"attach.tif"]];
  }
  else if ([itemIdentifier isEqualToString:kAddressBookToolbarIdentifier])
  {
    [theItem setLabel:NSLocalizedString(@"AddressBook", nil)];
    [theItem setToolTip:NSLocalizedString(@"AddressBookToolTip", nil)];
    [theItem setPaletteLabel:NSLocalizedString(@"AddressBookButton", nil)];
    [theItem setAction:@selector(openAddressBook:)];
    [theItem setImage:[NSImage imageNamed:@"address_book.tif"]];
  }
  else if ([itemIdentifier isEqualToString:kSaveToolbarIdentifier])
  {
    [theItem setLabel:NSLocalizedString(@"Save", nil)];
    [theItem setToolTip:NSLocalizedString(@"SaveToolTip", nil)];
    [theItem setPaletteLabel:NSLocalizedString(@"SaveButton", nil)];
    //[theItem setAction:@selector(saveAsDraft:)];
    [theItem setImage:[NSImage imageNamed:@"save.tif"]];
  }
  
  // Something strange, return nil
  else
    return nil;
  
  return theItem;
}

-(BOOL)validateToolbarItem:(NSToolbarItem *)theItem
{
  return YES;
}

@end

@implementation ComposerContentView

-(void)awakeFromNib
{
  mIsAttachmentViewVisible = NO;
  //[self showAttachments];
}

-(void)setBodyText:(NSString*)inBodyText
{
  [mBodyField setString:inBodyText];
}

-(NSString*)bodyText
{
  return [mBodyField string];
}

-(void)updateAttachmentList:(NSArray*)inAttachmentArr
{
  if (inAttachmentArr)
    [mAttachmentView updateAttachmentList:inAttachmentArr];
}

-(void)showAttachments
{
  [self addSubview:mAttachmentView];
  mIsAttachmentViewVisible = YES;
  [self display];
}

-(void)hideAttachments
{
  [mAttachmentView removeFromSuperview];
  mIsAttachmentViewVisible = NO;
  [self display];
}

-(void)setFrame:(NSRect)frameRect
{
  [super setFrame:frameRect];
  [self display];  // hack.
}

-(void)display
{
  if (mIsAttachmentViewVisible)
  {
    NSRect bounds = [self bounds];
    NSRect scrollFrame = [mScrollView frame];
    NSRect attachmentFrame = [mAttachmentView frame];
    
    attachmentFrame.origin = NSZeroPoint;
    attachmentFrame.size.width = bounds.size.width;
    
    scrollFrame.size.height = bounds.size.height - attachmentFrame.size.height - 1;
    scrollFrame.origin.y = attachmentFrame.size.height - 1;
    scrollFrame.size.width = bounds.size.width;
    
    [mScrollView setFrame:scrollFrame];
    [mAttachmentView setFrame:attachmentFrame];
  }
  else
    [mScrollView setFrame:[self bounds]];
  
  [super display];
}

-(void)resizeSubviewsWithOldSize:(NSSize)oldFrameSize
{
  [self display];
}

@end

@implementation SendingProgressWindow

-(void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
  [sheet orderOut:self];
}

-(void)showProgressDialog;
{
  [NSApp beginSheet:self
     modalForWindow:mParentWindow
      modalDelegate:self
     didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
        contextInfo:nil];
  
  [mProgIndicator startAnimation:self];
}

-(void)stopPorgressDialog
{
  [mProgIndicator stopAnimation:self];
  [NSApp endSheet:self];
}

-(void)updateProgress:(int)aProgress maxProgress:(int)aMaxProgress;
{
  //XXX update the progress bar.
}

-(void)setStatusString:(NSString*)aStatusString
{
  [mStatusField setStringValue:aStatusString];
}

@end
